#include "include/core/NodeList.h"

NodeList::NodeList()
    : thisNode(NULL)
{
    list = new QList<Node>();
}

NodeList::~NodeList() {
    delete list;
    if (thisNode != NULL) {
        delete thisNode;
    }
}

QVariant NodeList::data(const QModelIndex & index, int role) const {
    if (index.isValid() && index.row() >= 0 && index.row() < rowCount()) {
        Node node = list->at(index.row());
        if (role == Qt::DisplayRole) {
            return QString("%1:%2 - %3").arg(node.getAddress()).arg(node.getPort()).arg(node.getId());
        } else if (role == Qt::DecorationRole) {
            return QVariant(node.getPaintColor());
        } else if (role == Qt::ForegroundRole && node.getId() == lockedId) {
            return QVariant(QColor::fromRgb(255, 0, 0));
        }
    }
    return QVariant();
}

int NodeList::rowCount(const QModelIndex & /*parent*/) const {
    return list->length();
}

void NodeList::addNode(const Node &node, int index) {
    if (index < 0) {
        index = list->size();
    }
    beginInsertRows(QModelIndex(), index, index + 1);
    list->insert(index, node);
    endInsertRows();
}

void NodeList::addNode(const Node & prevNode, const Node & node) {
    int index = list->indexOf(prevNode) + 1;
    beginInsertRows(QModelIndex(), index, index + 1);
    list->insert(index, node);
    endInsertRows();
}

void NodeList::removeNode(const Node &node) {
    int index = list->indexOf(node);
    beginRemoveRows(QModelIndex(), index, index + 1);
    list->removeOne(node);
    endRemoveRows();
}

bool NodeList::isThisNodeFirst() {
    int thisNodeIndex = list->indexOf(*thisNode);
    return thisNodeIndex == 0;
}

void NodeList::setThisNode(Node * thisNode) {
    this->thisNode = thisNode;
}

const Node & NodeList::getPrevNode() const {
    int thisNodeIndex = list->indexOf(*thisNode);
    if (thisNodeIndex == 0) {
        return list->at(list->size() - 1);
    }
    return list->at(thisNodeIndex - 1);
}

const Node & NodeList::getNextNode() const {
    int thisNodeIndex = list->indexOf(*thisNode);
    if (thisNodeIndex == list->size() - 1) {
        return list->at(0);
    }
    return list->at(thisNodeIndex + 1);
}

const Node & NodeList::getNode(const QString & nodeId) const {
    int retIndex = 0;
    for (int i = 0; i < list->length(); ++i) {
        const Node n = list->at(i);
        if (n.getId() == nodeId) {
            retIndex = i;
            break;
        }
    }
    return list->at(retIndex);
}

Node & NodeList::getNode(const QString & nodeId) {
    int retIndex = 0;
    for (int i = 0; i < list->length(); ++i) {
        const Node n = list->at(i);
        if (n.getId() == nodeId) {
            retIndex = i;
            break;
        }
    }
    return (*list)[retIndex];
}

const Node & NodeList::getNode(const QString & address, quint16 port) const {
    int retIndex = 0;
    for (int i = 0; i < list->length(); ++i) {
        const Node n = list->at(i);
        if (n.getAddress() == address && n.getPort() == port) {
            retIndex = i;
            break;
        }
    }
    return list->at(retIndex);
}

void NodeList::setLockedId(const QString & lockedId) {
    beginResetModel();
    this->lockedId = lockedId;
    endResetModel();
}
